﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Xml.Serialization;
using Microsoft.Win32;

namespace TrafficWatcher.Infrastructure
{
    public class WindowsContext : IEnvironmentContext
    {
        private const string RegSubKeyNameToRunTheProgramAtWindowsStartup = @"Software\Microsoft\Windows\CurrentVersion\Run";
        private const string RegKeyNameToRunTheProgramAtWindowsStartup = @"HKEY_CURRENT_USER\" + RegSubKeyNameToRunTheProgramAtWindowsStartup;

        private readonly string appName;
        private readonly string appPath;
        private readonly string appDataFolder;
        private readonly string settingsPath;

        public WindowsContext()
        {
            appName = Assembly.GetExecutingAssembly().GetName().Name;
            appPath = Assembly.GetExecutingAssembly().Location;
            appDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            settingsPath = Path.Combine(appDataFolder, appName, "settings.xml");
        }

        public void OpenUrl(string url)
        {
            System.Diagnostics.Process.Start(url);
        }

        public void ManageTheApplicationRunAtStartup(bool run)
        {
            if (run)
            {
                Registry.SetValue(RegKeyNameToRunTheProgramAtWindowsStartup, appName, appPath);
            }
            else
            {
                using (var rk = Registry.CurrentUser.OpenSubKey(RegSubKeyNameToRunTheProgramAtWindowsStartup, RegistryKeyPermissionCheck.ReadWriteSubTree))
                {
                    rk.DeleteValue(appName, false);
                }
            }
        }

        public bool DoesTheApplicationRunAtStartup()
        {
            return (bool)Registry.GetValue(RegKeyNameToRunTheProgramAtWindowsStartup, appName, false);
        }

        public void ShutdownTheApplication()
        {
            Application.Current.Shutdown();
        }

        public void SaveSettings(SettingsDto settingsDto)
        {
            var directoryName = Path.GetDirectoryName(settingsPath);
            if ((!string.IsNullOrEmpty(directoryName)) && (!Directory.Exists(directoryName)))
            {
                Directory.CreateDirectory(directoryName);
            }

            using (var fs = new FileStream(settingsPath, FileMode.Create))
            using (var s = new StreamWriter(fs))
            {
                new XmlSerializer(typeof(SettingsDto)).Serialize(s, settingsDto);
            }
        }

        public SettingsDto LoadSettings()
        {
            try
            {
                using (var s = new StreamReader(settingsPath))
                {
                    return (SettingsDto) new XmlSerializer(typeof(SettingsDto)).Deserialize(s);
                }
            }
            catch (Exception)
            {
                return null;
            }
        }
    }
}
